using System;
using System.Collections.Generic;
using System.Text;

namespace Gencode.Common.Generics
{
    public class GenArrayList<T> : IGenerics<T>
    {
        private Node[] m_node;

        public GenArrayList()
        {
            m_node = null;
        }

        #region IGenerics<T> Members

        public void Add(T input)
        {
            if (m_node == null)
            {
                m_node = new Node[1];
                m_node[0] = new Node(input);
            }
            else
            {
                Node[] tmpNode = m_node;
                //Reset size to +1
                m_node = new Node[m_node.Length + 1];

                //Copy Nodes
                int i = 0;
                while (i < tmpNode.Length)
                {
                    m_node[i] = tmpNode[i];
                    i++;
                }

                //add new node
                m_node[i] = new Node(input);
            }
        }

        public void RemoveAt(int Index)
        {
			if (m_node != null)
			{
				if (Index < m_node.Length)
				{
					Node[] tmpNode = new Node[m_node.Length - 1];
					int i1 = 0;
					int i2 = 0;
					while (i1 < (m_node.Length))
					{
						if (i1 != Index)
						{
							tmpNode[i2] = m_node[i1];
							i2++;
						}
						i1++;
					}
					m_node = tmpNode;
				}
			}
        }

		public int Count
		{
			get
			{
				if (m_node != null)
					return m_node.Length;
				else
					return 0;
			}
		}

		/// <summary>
		/// Clears current List
		/// </summary>
		public void Clear()
		{
			m_node = null;
		}

        public T this[int Index]
        {
            get
            {
                if (Index < m_node.Length)
                    return m_node[Index].Data;

                return default(T);
            }
        }

        #endregion

        #region Node Class
        /// <summary>
        /// Node for generic list
        /// </summary>
        private class Node
        {
            public Node(T t)
            {
                data = t;
            }

            private T data;

            public T Data
            {
                get { return data; }
                set { data = value; }
            }
        }

        #endregion
    }
}
